
#include <BLabel>
#include <BGridLayout>
#include <BVBoxLayout>
#include <BMenu>

#include "WidgetPanel.h"

WidgetPanel::WidgetPanel(BWidget* parent) : BGroupBox(parent)
{
	_widget = 0;

	BMenu* widthPolicyMenu = new BMenu();
	{
		widthPolicyMenu->addAction("None")->setAsset(Policy_None);
		widthPolicyMenu->addAction("Fixed")->setAsset(Policy_Fixed);
		widthPolicyMenu->addAction("Preferred")->setAsset(Policy_Preferred);
		widthPolicyMenu->addAction("Shrinking")->setAsset(Policy_Shrinking);
		widthPolicyMenu->addAction("Expanding")->setAsset(Policy_Expanding);
		for (int i = 0; i < widthPolicyMenu->count(); i++)
			widthPolicyMenu->action(i)->setCheckable(true);
	}

	BMenu* heightPolicyMenu = new BMenu();
	{
		heightPolicyMenu->addAction("None")->setAsset(Policy_None);
		heightPolicyMenu->addAction("Fixed")->setAsset(Policy_Fixed);
		heightPolicyMenu->addAction("Preferred")->setAsset(Policy_Preferred);
		heightPolicyMenu->addAction("Shrinking")->setAsset(Policy_Shrinking);
		heightPolicyMenu->addAction("Expanding")->setAsset(Policy_Expanding);
		for (int i = 0; i < heightPolicyMenu->count(); i++)
			heightPolicyMenu->action(i)->setCheckable(true);
	}

	BGridLayout* gridLayout0 = new BGridLayout();
	{
		BLabel* nameLabel = new BLabel("name");
		_nameEdit = new BLineEdit();

		BLabel* titleLabel = new BLabel("title");
		_titleEdit = new BLineEdit();

		BLabel* framelessLabel = new BLabel("frameless");
		_framelessCheckBox = new BCheckBox();

		BLabel* tipsLabel = new BLabel("tips");
		_tipsEdit = new BLineEdit();

		BLabel* widthPolicyLabel = new BLabel("width-policy");
		_widthPolicyButton = new BButton(widthPolicyMenu);

		BLabel* heightPolicyLabel = new BLabel("height-policy");
		_heightPolicyButton = new BButton(heightPolicyMenu);

		gridLayout0->addWidget(0, 0, nameLabel);
		gridLayout0->addWidget(0, 1, _nameEdit);
		gridLayout0->addWidget(1, 0, titleLabel);
		gridLayout0->addWidget(1, 1, _titleEdit);
		gridLayout0->addWidget(2, 0, framelessLabel);
		gridLayout0->addWidget(2, 1, _framelessCheckBox);
		gridLayout0->addWidget(3, 0, tipsLabel);
		gridLayout0->addWidget(3, 1, _tipsEdit);
		gridLayout0->addWidget(4, 0, widthPolicyLabel);
		gridLayout0->addWidget(4, 1, _widthPolicyButton);
		gridLayout0->addWidget(5, 0, heightPolicyLabel);
		gridLayout0->addWidget(5, 1, _heightPolicyButton);
		gridLayout0->setColumnStretch(1, 100);
	}

	BGridLayout* gridLayout1 = new BGridLayout();
	{
		BLabel* fixedSizeLabel = new BLabel("fixed-size");
		_fixedWidthSpinBox = new BSpinBox();
		_fixedHeightSpinBox = new BSpinBox();

		BLabel* minSizeLabel = new BLabel("min-size");
		_minWidthSpinBox = new BSpinBox();
		_minHeightSpinBox = new BSpinBox();

		BLabel* maxSizeLabel = new BLabel("max-size");
		_maxWidthSpinBox = new BSpinBox();
		_maxHeightSpinBox = new BSpinBox();

		gridLayout1->addWidget(0, 0, fixedSizeLabel);
		gridLayout1->addWidget(0, 1, _fixedWidthSpinBox);
		gridLayout1->addWidget(0, 2, _fixedHeightSpinBox);
		gridLayout1->addWidget(1, 0, minSizeLabel);
		gridLayout1->addWidget(1, 1, _minWidthSpinBox);
		gridLayout1->addWidget(1, 2, _minHeightSpinBox);
		gridLayout1->addWidget(2, 0, maxSizeLabel);
		gridLayout1->addWidget(2, 1, _maxWidthSpinBox);
		gridLayout1->addWidget(2, 2, _maxHeightSpinBox);
	}

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(gridLayout0);
	vlayout->addLayout(gridLayout1);

	connect(this, Signal_AssetChanged, &WidgetPanel::slotAssetChanged);
	connect(_tipsEdit, Signal_EditFinished, &WidgetPanel::slotTipsEdited);
	connect(widthPolicyMenu, Signal_Checked, &WidgetPanel::slotWidthPolicyMenuChecked);
	connect(heightPolicyMenu, Signal_Checked, &WidgetPanel::slotHeightPolicyMenuChecked);
}

Policy WidgetPanel::policyFromMenu(BMenu* menu, BString& text)
{
	text.reset();
	Policy policy = 0;
	for (int i = 0; i < menu->count(); i++)
	{
		BAction* action = menu->action(i);
		if (action->checked())
		{
			text << action->text() << '|';
			PolicyFlag p = action->asset();
			policy |= p;
		}
	}
	text -= '|';
	return policy;
}
void WidgetPanel::policyToMenu(Policy policy, BMenu* menu, BString& text)
{
	text.reset();
	for (int i = 0; i < menu->count(); i++)
	{
		BAction* action = menu->action(i);
		PolicyFlag p = action->asset();
		action->setChecked(policy & p);
		if (action->checked())
			text << action->text() << '|';
	}
	text -= '|';
	_heightPolicyButton->setText(text);
}

void WidgetPanel::slotAssetChanged()
{
	_widget = this->asset();
	if (_widget)
	{
		this->setTitle(_widget->className());
		_nameEdit->setText(_widget->name());
		_titleEdit->setText(_widget->title());
		_tipsEdit->setText(_widget->tips());
		_framelessCheckBox->setChecked(_widget->frameless());

		_minWidthSpinBox->setValue(_widget->minWidth());
		_minHeightSpinBox->setValue(_widget->minHeight());
		_maxWidthSpinBox->setValue(_widget->maxWidth());
		_maxHeightSpinBox->setValue(_widget->maxHeight());
		_fixedWidthSpinBox->setValue(_widget->fixedWidth());
		_fixedHeightSpinBox->setValue(_widget->fixedHeight());

		BString widthPolicyText;
		policyToMenu(_widget->widthPolicy(), _widthPolicyButton->menu(), widthPolicyText);
		_widthPolicyButton->setText(widthPolicyText);

		BString heightPolicyText;
		policyToMenu(_widget->heightPolicy(), _heightPolicyButton->menu(), heightPolicyText);
		_heightPolicyButton->setText(heightPolicyText);
	}
}
void WidgetPanel::slotTipsEdited(BObject* object, const BValue& value)
{
	const BString& text = value;
	_widget->setTips(text);
}
void WidgetPanel::slotWidthPolicyMenuChecked(BObject* object, const BValue& value)
{
	BMenu* menu = dynamic_cast<BMenu*>(object);
	BString text;
	Policy policy = policyFromMenu(menu, text);
	_widthPolicyButton->setText(text);
	_widget->setWidthPolicy(policy);
}
void WidgetPanel::slotHeightPolicyMenuChecked(BObject* object, const BValue& value)
{
	BMenu* menu = dynamic_cast<BMenu*>(object);
	BString text;
	Policy policy = policyFromMenu(menu, text);
	_heightPolicyButton->setText(text);
	_widget->setHeightPolicy(policy);
}

